package com.tianji.learning.handler;

import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.DateUtils;
import com.tianji.learning.constants.RedisConstants;
import com.tianji.learning.domain.po.PointsBoard;
import com.tianji.learning.domain.vo.PointsBoardItemVO;
import com.tianji.learning.service.IPointsBoardSeasonService;
import com.tianji.learning.service.IPointsBoardService;
import com.tianji.learning.service.IPointsRecordService;
import com.tianji.learning.service.impl.PointsBoardSeasonServiceImpl;
import com.tianji.learning.service.impl.PointsRecordServiceImpl;
import com.tianji.learning.utils.TableInfoContext;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;

/**
 * @Author: 19311
 * @CreateTime: 2025-03-28
 * @Description: 积分排行榜的每月分布式持久化
 * @Version: 1.0
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class PointsBoardPersistentHandler {

    private final IPointsBoardService pointsBoardService;
    private final IPointsBoardSeasonService seasonService;
    private final StringRedisTemplate redisTemplate;
    @XxlJob("createTable")
    public void createTable() {
        // 1、查询上月时间
        LocalDateTime time = LocalDateTime.now().minusMonths(1);
        // 2、查询赛季id
        time.minusMonths(1);
        Integer season = seasonService.querySeasonByTime(time);
        if (season == null) {
            // 赛季不存在
            return;
        }
        // 3、创建表
        pointsBoardService.createPointsBoardTableBySeason(season);
    }

    /**
     * 持久化积分排行榜到数据库
     */
    @XxlJob("savePointsBoard2DB")
    public void savePointsBoard2DB() {
        // 1、查询上月时间
        LocalDateTime time = LocalDateTime.now().minusMonths(1);
        // 2、查询赛季id
        // 2.1、拼接key
        String key = RedisConstants.POINTS_BOARD_KEY_PREFIX + LocalDateTime.now().format(DateUtils.POINTS_BOARD_SUFFIX_FORMATTER);
        // 2.2、
        Integer season = seasonService.querySeasonByTime(time);
        // 2.3 计算动态表名
        TableInfoContext.setTableName("points_board_" + season);
        // 查询数据库
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();
        int pageNo = shardIndex + 1;
        int pageSize = 1;
        while (true) {
            List<PointsBoard> boardList = pointsBoardService.saveCurrentBoardToDB(key, pageNo, pageSize);
            if (CollUtils.isEmpty(boardList)) {
                break;
            }
            boardList.forEach(b->{
                b.setId(Long.valueOf(b.getRank()));
                b.setRank(null);
            });
            // 2.5 持久化到数据库
            pointsBoardService.saveBatch(boardList);
            pageNo += shardTotal;
        }
        TableInfoContext.remove();
    }

    /**
     * 卸磨杀驴，可以清除redis积分榜了
     */
    @XxlJob("clearPointsBoard")
    public void clearPointsBoard() {
        redisTemplate.unlink(RedisConstants.POINTS_BOARD_KEY_PREFIX + LocalDateTime.now().format(DateUtils.POINTS_BOARD_SUFFIX_FORMATTER));
    }

}
